package com.cloudfast.manager.impl;

import com.cloudfast.config.property.c.MinioProperty;
import com.cloudfast.manager.FileStorageManager;
import com.cloudfast.response.FileResponse;
import com.cloudfast.utils.FileUtils;
import io.minio.*;
import io.minio.messages.DeleteObject;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.multipart.MultipartFile;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class MinioStorageService extends BaseManagerImpl implements FileStorageManager {
    private static final Logger logger = LoggerFactory.getLogger(Logger.class);

    @Autowired
    private MinioProperty storageProperty;

    private MinioClient minioClient;

    public MinioStorageService(MinioProperty storageProperty, int maxFileSize) {
        this.storageProperty = storageProperty;
        this.maxFileSize = maxFileSize;
        minioClient = MinioClient.builder().endpoint(storageProperty.getEndpoint())
                .credentials(storageProperty.getAccessKey(), storageProperty.getSecretKey()).build();
        // 判断bucketName是否存在不存在就创建bucketName
        existBucket(storageProperty.getBucketName());
    }

    @Override
    public FileResponse upload(MultipartFile file) throws IOException {
        return upload(file, null);
    }

    @Override
    public FileResponse upload(MultipartFile file, String prefix) throws IOException {
        try {
            // 文件不能为空
            if (file == null) {
                throw new RuntimeException("文件不能为空");
            }

            // 不能超过最大支持
            if (file.getSize() > maxFileSize) {
                throw new RuntimeException("文件太大,已超出最大支持范围:" + maxFileSize);
            }
            // 获取文件的真实 名称
            String originalName = file.getOriginalFilename();
            // 获取后缀名称
            String suffix = FileUtils.getFilenameSuffix(originalName);
            // 获取需要保存的文件名称
            String radomName = FileUtils.getRadomName() + "." + suffix;

            // 获取文件保存的路径
            String storageFilePath = "/" + FileUtils.getYmdPath() + "/";
            if (StringUtils.isNotEmpty(prefix)) {
                storageFilePath = "/" + prefix + "/" + FileUtils.getYmdPath() + "/";
            }
            minioClient.putObject(PutObjectArgs.builder().bucket(storageProperty.getBucketName())
                    .object(storageFilePath + "/" + radomName)
                    .stream(file.getInputStream(), file.getInputStream().available(), -1)
                    .contentType(file.getContentType()).build());

            return new FileResponse(originalName, (storageFilePath + "/" + radomName).replaceAll("//", "/"), radomName,
                    suffix, file.getSize(), (storageProperty.getBrowserPrefix() + "/" + storageProperty.getBucketName()
                    + "/" + (storageFilePath + "/" + radomName)).replaceAll("//", "/"));
        } catch (Exception e) {
            logger.error(e.getMessage());
            return null;
        }

    }

    @Override
    public FileResponse upload(InputStream stream, String filePath, String fileName) {
        return null;
    }

    @Override
    public byte[] download(String filePath) {
        InputStream in = null;
        ByteArrayOutputStream out = null;
        byte downloadByte[] = null;
        try {
            in = minioClient.getObject(
                    GetObjectArgs.builder().bucket(storageProperty.getBucketName()).object(filePath).build());
            out = new ByteArrayOutputStream();
            IOUtils.copy(in, out);
            downloadByte = out.toByteArray();
        } catch (Exception e) {
            logger.error("", "读取文件流失败.");
        }

        return downloadByte;
    }

    @Override
    public int deleteFile(String filePath) {
        List<String> objects = new ArrayList<>();
        objects.add(filePath);
        List<DeleteObject> dos = objects.stream().map(e -> new DeleteObject(e)).collect(Collectors.toList());
        minioClient.removeObjects(
                RemoveObjectsArgs.builder().bucket(storageProperty.getBucketName()).objects(dos).build());
        return 1;
    }

    @Override
    public List<File> iterationFile(String rootPath) {
        return null;
    }

    /**
     * description: 判断bucket是否存在，不存在则创建
     *
     * @return: void
     */
    private void existBucket(String name) {
        try {
            boolean exists = minioClient.bucketExists(BucketExistsArgs.builder().bucket(name).build());
            if (!exists) {
                minioClient.makeBucket(MakeBucketArgs.builder().bucket(name).build());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
